import React from 'react';
import { Tree, Icon } from 'antd';
import _ from 'lodash';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { actions as assetManageActions, TreeSelectFilterType } from '../../reducer';
import PropTypes from 'prop-types';
import './index.less';

function formatTreeData(data = [], belong = {}, sort = false) {
  const treeData = [];
  for (const item of data) {
    if (!item.name) {
      continue;
    }
    item.belong = _.isEmpty(belong) ? _.pick(item, ['_id', 'name']) : belong;
    const option = {
      title: (
        <>
          <span className={`name ${item.count === 0 ? 'disabled' : null}`} title={item.name}>
            {item.name}
          </span>
          <span className={`count ${item.count === 0 ? 'disabled' : null}`} data-is-count="true">
            {item.count}
          </span>
        </>
      ),
      value: item.count,
      item: item,
      key: item._id,
      children: formatTreeData(item.children || [], item.belong, true),
      disabled: item.count === 0
    };
    treeData.push(option);
  }

  return sort ? _.sortBy(treeData, 'value').reverse() : treeData;
}

class StatsFilter extends React.Component {
  static propTypes = {
    assetStats: PropTypes.object,
    attributeFilter: PropTypes.object,
    setState: PropTypes.func,
    modules: PropTypes.array
  };
  constructor(props) {
    super(props);
    const treeData = this.getTreeData({});
    this.state = {
      treeData: treeData,
      expandedKeys: [_.get(treeData, [0, 'key'])].filter(Boolean)
    };
  }

  componentDidUpdate(prevProps) {
    if (prevProps.assetStats !== this.props.assetStats) {
      const { assetStats = [] } = this.props;
      const treeData = this.getTreeData(assetStats);
      this.setState({
        treeData
      });
    }
  }

  getTreeData = (assetStats = {}) => {
    const {
      count = {},
      assetCategory = [],
      organization = [],
      location = [],
      waf = [],
      service = [],
      os = [],
      oneday = [],
      tag = [],
      staffNickname = [],
      origin = []
    } = assetStats;

    // 国产化系统只展示两级，目前在后台的国产化系统的第二级设置为null
    const recombineCategories = ['国产化系统'];
    const domesticOsIndex = os.findIndex(_os => recombineCategories.includes(_os.name));
    if (domesticOsIndex >= 0) {
      // 将第三级替换成第二级
      const level2 = os[domesticOsIndex].children[0] || {};
      os[domesticOsIndex].children = level2.children || [];
      // os[domesticOsIndex].count = level2.count;
    }

    const { modules = [] } = this.props;
    const hasOneDayModule = modules.includes('1day');

    const data = [
      {
        _id: 'assetCategory',
        name: '资产分类',
        children: assetCategory
      },
      {
        _id: 'organization',
        name: '部门',
        children: organization
      },
      {
        _id: 'location',
        name: '地理位置',
        children: location
      },
      {
        _id: 'waf',
        name: '防护信息',
        children: waf
      },
      {
        _id: 'service',
        name: '服务',
        children: service
      },
      {
        _id: 'os',
        name: '操作系统',
        children: os
      },
      hasOneDayModule && {
        _id: 'oneday',
        name: '漏洞',
        children: oneday
      },
      {
        _id: 'tag',
        name: '标签',
        children: tag
      },
      {
        _id: 'origin',
        name: '来源',
        children: origin
      },
      {
        _id: 'staffNickname',
        name: '管理员',
        children: staffNickname
      }
    ].filter(Boolean);
    data.forEach(item => {
      item.isTop = true;
      item.count = _.get(count, item._id, 0);
    });
    return formatTreeData(data);
  };

  recursiveNodes = (node, pickParentNode) => {
    const nodes = [];
    const children = _.get(node, 'children', []);

    if (!node.isTop && (pickParentNode || _.isEmpty(children))) {
      nodes.push(node);
    }

    if (!_.isEmpty(children)) {
      _.forEach(node.children, child => {
        nodes.push(...this.recursiveNodes(child, pickParentNode));
      });
    }

    return nodes;
  };

  onSelectKey = (selectKeys, e) => {
    // 判断是展开还是筛选
    const isCount = _.get(e, 'nativeEvent.path[0].dataset.isCount');

    const nodeItem = _.get(e, 'node.props.item', {});
    const isLeafNode = !_.get(nodeItem, 'children.length');

    if (isCount || isLeafNode) {
      // 点击叶子节点或数字触发筛选
      // if (isLeafNode) {
      //   // 重置之前节点字体颜色
      //   const preNodes = document.querySelectorAll('.stats-filter .ant-tree-title .name.active');
      //   for (const preNode of preNodes) {
      //     preNode.classList.remove('active');
      //   }
      //   const targetNode = _.get(e, 'nativeEvent.target');
      //   if (targetNode && targetNode.classList) {
      //     targetNode.classList.add('active');
      //   }
      // }

      const { attributeFilter, setState } = this.props;
      const newAttributeFilter = _.cloneDeep(attributeFilter);
      // 获取所有叶子节点并组装
      const belong = nodeItem.belong;
      if (_.isEmpty(belong)) {
        return;
      }
      const pickParent = ['organization', 'assetCategory'].includes(belong._id);
      const leafNodes = this.recursiveNodes(nodeItem, pickParent);
      const value = _.map(leafNodes, node => {
        const item = {
          label: node.name,
          value: node._id
        };
        if (belong._id === 'location') {
          item.location = _.get(node, 'location', {});
        }
        return item;
      });
      const preMoreActionValue = _.get(newAttributeFilter, ['moreAction', 'value'], []);
      if (!_.map(preMoreActionValue, 'value').includes(belong._id)) {
        newAttributeFilter.moreAction = {
          type: TreeSelectFilterType,
          value: preMoreActionValue.concat({
            label: belong.name,
            value: belong._id
          })
        };
      }
      newAttributeFilter[belong._id] = {
        type: TreeSelectFilterType,
        value: value
      };

      setState({
        attributeFilter: newAttributeFilter,
        pagaition: {
          page: 1,
          pageSize: 10
        }
      });
      return;
    } else {
      // 展开下一级
      const key = _.get(e, 'node.props.eventKey');
      if (!key) {
        return;
      }
      const { expandedKeys } = this.state;
      if (_.includes(expandedKeys, key)) {
        this.setState({
          expandedKeys: expandedKeys.filter(k => k !== key)
        });
      } else {
        this.setState({
          expandedKeys: expandedKeys.concat(key)
        });
      }
    }
  };

  onExpand = expandedKeys => {
    this.setState({ expandedKeys });
  };

  render() {
    const { expandedKeys, treeData } = this.state;

    return (
      <div className="stats-filter">
        <Tree
          showIcon
          expandedKeys={expandedKeys}
          onSelect={this.onSelectKey}
          icon={<Icon type="folder" />}
          onExpand={this.onExpand}
          treeData={treeData}
        />
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    assetStats: _.get(state, 'assetManage.assetStats', {}),
    attributeFilter: _.get(state, 'assetManage.attributeFilter', {}),
    modules: _.get(state, 'auth.cert.modules', [])
  };
};

const mapDispatchToProps = dispatch => {
  return {
    ...bindActionCreators(assetManageActions, dispatch)
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(StatsFilter);
